﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Runtime.Serialization;
using System.Diagnostics;

namespace Airport
{
    [DataContract]
    public class RouteNode : Node, IEquatable<RouteNode>
    {
        /// <summary>
        /// The amount of time in seconds within which two Planes are considered to occupy the same RouteNode.
        /// </summary>
        private TimeSpan _separationTime;

        private DateTime _predictedTOA;
        private DateTime _actualTOA;
        private DateTime _expireTime;        

        public RouteNode()
            : base()
        {
            _separationTime = new TimeSpan(0, 0, 60);
        }

        public RouteNode(int id, int x, int y)
            : base(id, x, y)
        {
            _separationTime = new TimeSpan(0, 0, 60);
        }

        public RouteNode(Node node)
        {
            base.XPos = node.XPos;
            base.YPos = node.YPos;
            base.NodeId = node.NodeId;
            base.IsHoldBar = node.IsHoldBar;
            // Don't copy Neighbors because we don't need them for RouteNodes
            _separationTime = new TimeSpan(0, 0, 60);
        }

        [DataMember]
        public DateTime PredictedTOA
        {
            get
            {
                return _predictedTOA;
            }

            set
            {
                if (_predictedTOA != value)
                {
                    _predictedTOA = value;
                }
            }
        }

        [DataMember]
        public DateTime ActualTOA
        {
            get
            {
                return _actualTOA;
            }

            set
            {
                if (_actualTOA != value)
                {
                    _actualTOA = value;
                }
            }
        }

        [DataMember]
        public DateTime ExpireTime
        {
            get
            {
                return _expireTime;
            }

            set
            {
                if (_expireTime != value)
                {
                    _expireTime = value;
                }
            }
        }        

        public bool Equals(RouteNode other)
        {
            TimeSpan separationTime = new TimeSpan(0, 0, 60);
            if (other == null)
            {
                return false;
            }
            
            if (!base.Equals((Node)other))
            {
                return false;
            }
            
            TimeSpan interval = _predictedTOA - other._predictedTOA;
            /*
            Debug.WriteLine("  ** RouteNode.Equals: _predictedTOA = " + _predictedTOA
                + ", other._predictedTOA = " + other._predictedTOA
                + ", interval = " + interval
                + ", interval.Duraction() = " + interval.Duration()
                + ", _separationTime = " + separationTime
                + ", interval.Duration() <= _separationTime = " + (interval.Duration() <= separationTime));
            */
            return interval.Duration() <= separationTime;

            /*
            if (_predictedTOA != other._predictedTOA)
            {
                return false;
            }
            
            if (_actualTOA != other._actualTOA)
            {
                return false;
            }

            if (_expireTime != other._expireTime)
            {
                return false;
            }
            
            return true;
            */
        }

        public override string ToString()
        {
            string routeNodeString = base.ToString();

            routeNodeString += " " + _predictedTOA.ToString();

            return routeNodeString;
        }
    }

    public class PredictedTOACompare : Comparer<RouteNode>
    {
        /// <summary>
        /// The amount of time in seconds within which two Planes are considered to occupy the same RouteNode.
        /// </summary>
        private TimeSpan _separationTime = new TimeSpan(0, 0, 60);

        public override int Compare(RouteNode x, RouteNode y)
        {
            TimeSpan interval = x.PredictedTOA - y.PredictedTOA;
            
            if (interval.Duration() <= _separationTime)
            {
                return 0;
            }
            else
            {                
                return x.PredictedTOA.CompareTo(y.PredictedTOA);
            }
        }
    }
}